local P = ClassFromFile(...)

local curTutorial
local curFinishCallback
local curStepIndex
local curWin
local curUI
local restrictingControl
local waitEndTime
local restguidance 
local nextStepWaitTime




function P.Init()
	LateUpdateBeat:Add(P.LateUpdate, nil);
end

function P.Destroy()
	LateUpdateBeat:Remove(P.LateUpdate, nil);
	P.FinishTutorial(true)
end

function P.LateUpdate()
	


	if not curTutorial then
		return
	end

	if not curStepIndex then
		P.NextStep()
	end

	if waitEndTime and Time.time >= waitEndTime then
		waitEndTime = nil
		if P.NextStep() then
			P.FinishTutorial()
		end
		return
	end
	if nextStepWaitTime and Time.time >= nextStepWaitTime then
		nextStepWaitTime = nil
		if P.NextStep() then
			P.FinishTutorial()
		end
		return
	end

	local curStep = curTutorial.steps[curStepIndex]

	-- find window
	if not curWin then
		if curStep.useOldWin then
			while true do
				local winProxy = RootWindowManager.instance:GetCurWindow()
				if winProxy.win then
					if winProxy.winName ~= curStep.winName then
						RootWindowManager.instance:HideWindow(winProxy.winName)
					else
						curWin = winProxy.win
						break
					end
				else
					break
				end
			end
		else
			local winProxy = RootWindowManager.instance:GetCurWindow()
			if winProxy.win and winProxy.winName == curStep.winName then
				curWin = winProxy.win
			end
		end

		if curWin and curStep.noUiConstrait then
			if curStep.initFun then
				curStep:initFun(curWin, nil)
			end

			RootWindowManager.instance:GetRestrictControlRegionManager():RemoveControlObj(true)
			RootWindowManager.instance:GetRestrictControlRegionManager():EnableBlock(false)
		end
	end


	if not curStep.noUiConstrait then
		-- find ui
		if not curUI and curWin then
			curUI = P.GetUiObj(curStep)

			if curUI then
				if curStep.initFun then
					curStep:initFun(curWin, curUI)
				end
			end
		end

		-- restrict control
		if not restrictingControl and curUI then
			restrictingControl = true

			local controlRegionObj = nil
			if curStep.regionUiPath then
				controlRegionObj = curWin.transform:Find(curStep.regionUiPath)
			end

			RootWindowManager.instance:GetRestrictControlRegionManager():RestrictControl(curUI.gameObject, controlRegionObj and controlRegionObj.gameObject, curStep.effect, curStep.controlType or 0, curStep.customControl, not curStep.checkStateFunName and P.OnControlFinish or nil)
			RootWindowManager.instance:GetRestrictControlRegionManager():ShowFinger(not curStep.hideFinger)

			if curStep.regions then
				for i = 1,#curStep.regions do
					local region = curStep.regions[i]
					local regionUI = P.GetUiObj(region)
					if regionUI then
						local regionInfo = RootWindowManager.instance:GetRestrictControlRegionManager():AddRegion(regionUI.gameObject, region.isCircle, false)
						regionInfo:GetLabel():SetText(region.text)
						regionInfo.textPos = region.textPosition
					end
				end
			else
				local regionInfo = RootWindowManager.instance:GetRestrictControlRegionManager():AddRegion(curUI.gameObject, curStep.isCircle, true)
				RootWindowManager.instance:GetRestrictControlRegionManager():ShowInstruction(true, curStep.textPosition)
				local label = RootWindowManager.instance:GetRestrictControlRegionManager().instructionLabel
				label:SetText(curStep.text)
				-- regionInfo.textPos = curStep.textPosition
				if regionInfo and curStep.highlight then
					local prefab = ResourceManager.LoadAsset(curStep.highlightPrefab)
					local hightprefab = UnityEngine.GameObject.Instantiate(prefab);
					hightprefab.transform:SetParent(regionInfo.obj.transform,false)
					local uiweight1 = regionInfo.obj:GetComponent('UIWidget');
					local uiweight = hightprefab:GetComponent('UIWidget');
					uiweight.height = uiweight1.height
					uiweight.width = uiweight1.width
				end
			end
			if curStep.nextStepWaitTime then
				nextStepWaitTime = Time.time + curStep.nextStepWaitTime
			end
		end



		if restrictingControl and curUI and curStep.checkStateFunName then
			local winLuaObj = curWin:GetLuaObj()
			local fun = winLuaObj[curStep.checkStateFunName]
			if not fun then
				logError("not found fun: "..tostring(curStep.checkStateFunName))
			else
				if fun(winLuaObj, curStep.param) then
					P.OnControlFinish()
				end
			end
		end
	end
	---- 新增的
	if not restguidance then
		restguidance = true
		if curStep.guidancetext then
			local guidanceBg = RootWindowManager.instance:GetRestrictControlRegionManager().guidanceBg
			guidanceBg:SetActive(true)
			local label = RootWindowManager.instance:GetRestrictControlRegionManager().guidanceLab
			label:SetText(curStep.guidancetext)
		else
			local guidanceBg = RootWindowManager.instance:GetRestrictControlRegionManager().guidanceBg
			guidanceBg:SetActive(false)
			local label = RootWindowManager.instance:GetRestrictControlRegionManager().guidanceLab
			label:SetText("")
		end

		local nextStepBtn = RootWindowManager.instance:GetRestrictControlRegionManager().nextStepBtn
		nextStepBtn:SetActive(curStep.needNextStep)



	end

	if curStep.checkEndFun and curStep:checkEndFun(curWin, curUI) then
		if P.NextStep() then
			P.FinishTutorial()
		end
	end
end

function P.GetUiObj(info)
	local curUI = nil
	if info.uiName then
		curUI = curWin:GetLuaObj()._dataObj[info.uiName]
		if not curUI then
			logError("not found ui with name: "..tostring(info.uiName))
		end
	elseif info.uiPath then
		curUI = curWin.transform:Find(info.uiPath)
		if not curUI then
			logError("not found ui with path: "..tostring(info.uiPath))
		end
	elseif info.getWidgetFunName then
		local winLuaObj = curWin:GetLuaObj()
		local fun = winLuaObj[info.getWidgetFunName]
		if not fun then
			logError("not found fun: "..tostring(info.getWidgetFunName))
		else
			curUI = fun(winLuaObj, info.param)
			if not curUI then
				logError("not found ui with getWidgetFunName: "..tostring(info.getWidgetFunName).."  param: "..tostring(info.param))
			end
		end
	end
	return curUI
end

function P.OnControlFinish()
	if curStepIndex then
		local curStep = curTutorial.steps[curStepIndex]
		if curStep.checkEndFun then
			return false
		end

		if curStep and curStep.waitTime then
			waitEndTime = Time.time + curStep.waitTime
			return true
		end
	end

	if P.NextStep() then
		P.FinishTutorial()
	end
	return true
end

function P.StartTutorial(tutorial, finishCallback)
	if curTutorial ~= nil then
		return
	end
	curTutorial = tutorial
	curFinishCallback = finishCallback
	if curTutorial == nil or #curTutorial.steps <= 0 then
		return
	end

	local skipBtn = RootWindowManager.instance:GetRestrictControlRegionManager().skipBtn
	UIEventListener.Get(skipBtn).onClick = UIEventListener.VoidDelegate(P.OpenSkip);
	skipBtn:SetActive(not curTutorial.isHideSkipBtn)

	local nextStepBtn = RootWindowManager.instance:GetRestrictControlRegionManager().nextStepBtn
	UIEventListener.Get(nextStepBtn).onClick = UIEventListener.VoidDelegate(P.OnClickNextStep);

end

function P.FinishTutorial(isDestroy)
	if curTutorial == nil then
		return
	end

	if curTutorial.endFun then
		curTutorial.endFun(curWin)
	end
	if RootWindowManager.instance:GetRestrictControlRegionManager() then
		local skipBtn = RootWindowManager.instance:GetRestrictControlRegionManager().skipBtn
		UIEventListener.Get(skipBtn).onClick = nil
	end
	if RootWindowManager.instance:GetRestrictControlRegionManager() then
		local nextStepBtn = RootWindowManager.instance:GetRestrictControlRegionManager().nextStepBtn
		UIEventListener.Get(nextStepBtn).onClick = nil
		nextStepBtn:SetActive(false)
	end

	curTutorial = nil
	curStepIndex = nil
	curWin = nil
	curUI = nil
	restrictingControl = nil
	restguidance = nil
	nextStepWaitTime = nil
	local callback = curFinishCallback
	curFinishCallback = nil

	local regionManager = RootWindowManager.instance:GetRestrictControlRegionManager();
	if not regionManager then
		return
	end

	regionManager:RemoveControlObj(true)
	regionManager:EnableBlock(false)

	if not isDestroy then
		if callback then
			callback()
		end
	end
end

function P.NextStep()
	if curTutorial == nil then
		return
	end
	if not curStepIndex then
		curStepIndex = 1
	else
		RootWindowManager.instance:GetRestrictControlRegionManager():RemoveControlObj(true)

		local curStep = curTutorial.steps[curStepIndex]
		if curStep and curStep.endFun then
			curStep:endFun(curWin, curUI)
		end

		curStepIndex = curStepIndex + 1

		if curStepIndex > #curTutorial.steps then
			return true
		end
	end

	curWin = nil
	curUI = nil
	restrictingControl = nil
	restguidance = nil
	nextStepWaitTime = nil
end

function P.OpenSkip()
	local ConfireSureBack = CreateCallBack(P.Skip);
	local winProxy2 = RootWindowManager.instance:ShowWindow("TwoBtnDialog", RootWindowManager.alertDialogLayer9, false);
    winProxy2:Init({title = LuaTextKey.prompt_title, content = LuaTextKey.tutorial_skip, okBtnClick = ConfireSureBack, okBtnText = LuaTextKey.confirm, cancelBtnText = LuaTextKey.cancel})
end
function P.OnClickNextStep()
	if P.NextStep() then
		P.FinishTutorial()
	end
end
function P.Skip()
	if not curStepIndex then
		return
	end

	if not curWin or not curUI then
		return
	end
	
	local curStep = curTutorial.steps[curStepIndex]
	if curStep and curStep.endFun then
		curStep:endFun(curWin, curUI)
	end
	--KBEngineLua.player().cellCall.Cell_SkipTutorial()
	P.FinishTutorial()
end